
package tuding.android.bigplanettracks.maps.tuding;


import tuding.android.bigplanettracks.BigPlanet;
import tuding.android.bigplanettracks.util.Preferences;
import android.location.GpsStatus;
import android.location.Location;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;

public class AutoPause {
	
	//parms:

	private static boolean GPSISWORKING = false;
	private static boolean GPSISBLINKING = false;
	//public static boolean GPSISREGISTERED = false;
	
	public static boolean isGPSFix = false;
	public static boolean First_start_flag = true;
	public static int First_start_delay_counter = 2; // 2
	public static int PauseGear = 0; // 0: no sleep, 1: update once per min, 2: update once per 2 min, 3: 3 mins , 4: 4mins
	
	//public static int[] PauseInterval = {3000, 6000, 8000, 10000, 12000}; // for testuse
	//public static int CountDownInitVal = 10000; // for testuse
	public static int[] PauseInterval = {4000, 9000, 18000, 30000, 120000, 240000, 600000};
	public static int CountDownInitVal = 30000; // 30000 second
	
	public static Location previousLocation; // good location: acc<50m
	public static long mGPSStartTimeMillis = 0;
	private static int MAX_Count_before_switch_gear = 2; // 
	private static int Count_before_switch_gear = 0;
	public static int MinDistance = 10; // 10m
	public static boolean Location_Changed_flag = false;

	public static boolean fFixDeadLock = false;
	
	public static boolean bStopThread = false;
	
	private Thread ap_thread;
	
	
	public AutoPause() {
		
	}
	
	
	
	public void AP_enable() {
		Log.i("GPS", "Thread is starting");
		bStopThread = false;
		ap_thread = new Thread("AP_Thread") {
			@Override
			public void run() {
				while(bStopThread == false) {
					try {
						Log.i("GPS", "fixDeadLockTask!:" +(SystemClock.elapsedRealtime() - mGPSStartTimeMillis)+" ");
						
						if((SystemClock.elapsedRealtime() - mGPSStartTimeMillis >= 50000 // 50s
					     		&& Location_Changed_flag == false
					     		&& First_start_flag == false
					     		) 
					     ) {
							
							if(BigPlanet.locationManager != null && BigPlanet.gpsLocationListener != null) {
								BigPlanet.locationManager.removeUpdates(BigPlanet.gpsLocationListener);
								Message msg = new Message(); // show GPS
								msg.what = 4;
								BigPlanet.updateLocationUpdateHandler.sendMessage(msg);
								fFixDeadLock = true;
								Log.i("GPS", "remove update!");
							}
						}
						
						
						// the second part: handle the location change stuffs
						if(BigPlanet.Paused_flag == false || BigPlanet.isGPSTracking == true) {
							if(Location_Changed_flag == true) {
							    Location_Changed_flag = false;
							    if(PauseGear != getGearFromGPSIntervalValue()) {// if pausegear is not match with current update interval, then update it
							    	PauseGear = getGearFromGPSIntervalValue();
							    	Message msg = new Message(); 
									msg.what = 2;
									msg.arg1 = Preferences.getGPSIntervalValue();
									BigPlanet.updateLocationUpdateHandler.sendMessage(msg);
							    	
							    }
								Log.i("GPS", "timerTask: location changed in past 30s");
							} else { 
								// maybe we need synchronized(), but current I think it is ok as
								// when First_start_flag is true, First_start_delay_counter is 2or1
								// First_start_flag will not be assigned to false again
								if(First_start_flag == true) {
									if(--First_start_delay_counter <= 0)	{
										First_start_flag = false;
										Log.i("GPS", "timerTask: First_start_delay_counter <= 0");
									} else {
										Log.i("GPS", "timerTask: First_start_delay_counter--:"+First_start_delay_counter);
									}
								} else {
									if((++Count_before_switch_gear)>MAX_Count_before_switch_gear*PauseGear) {
										Count_before_switch_gear = 0;
										AP_sleep_deeper();
									} else {
										Log.i("GPS", "Count_before_switch_gear is "+Count_before_switch_gear);
									}
								}
							}
						} else {
							Log.i("GPS", "Paused or isGPSTracking!");
						}
						// wait for 30s for next check
						Thread.sleep(30000);
					} catch(Exception e) {
						Log.e("GPS", "exception"+e.toString());
						//e.printStackTrace();
					}
				}
			}
		};
		try {
			ap_thread.start();
		} catch(Exception e) {
			Log.i("AP", "ap_thread is already started!");
		}
	}
	

	
	public void AP_disable() {
		Log.i("AP", "Thread is stopping");
		bStopThread = true;
		if(ap_thread != null) ap_thread.interrupt();
	}
	
	
	private void AP_sleep_deeper() {
		if(GPSISWORKING == false) {
			if(PauseGear < (PauseInterval.length-1)){
				PauseGear++;
				if(PauseGear < getGearFromGPSIntervalValue()) PauseGear = getGearFromGPSIntervalValue();
				Log.i("GPS","---> sleep deeper: interval to "+PauseInterval[PauseGear]);
				// en-large time interval for gps
				if(  BigPlanet.locationManager != null ) { // fFixDeadLock==false means 
					Log.i("GPS","---> sleep deeper: send out intent");
					Message msg = new Message(); 
					msg.what = 1;
					BigPlanet.updateLocationUpdateHandler.sendMessage(msg);
				}
			}
			
			// if just fix deadlock, then there is no location update currently, need register one
			else if(fFixDeadLock == true) {
				fFixDeadLock = false;
				if(BigPlanet.locationManager != null) {
					Message msg = new Message(); 
					msg.what = 1;
					BigPlanet.updateLocationUpdateHandler.sendMessage(msg);
				}
			}
		}
	}
	
	public void AP_sleep_lighter() {
		
		First_start_delay_counter = 2; // 2x30s ~ 3x30s
		First_start_flag = true;
		if(GPSISWORKING == false) {
		//if(true) {
			Log.i("GPS","---> sleep comeback: interval to "+PauseInterval[PauseGear]);		
			if(BigPlanet.locationManager != null) {
				Count_before_switch_gear = 0;
				Message msg = new Message(); 
				msg.what = 1;
				BigPlanet.updateLocationUpdateHandler.sendMessage(msg);
			}
		}
	}
	
	public static int getGearFromGPSIntervalValue() {
		int theV = Preferences.getGPSIntervalValue();
		if(theV <= 4000) return 0;
		else if(theV <= 9000) return 1;
		else if(theV <= 18000) return 2;
		else if(theV <= 30000) return 3;
		else if(theV <= 120000) return 4;
		else if(theV <= 240000) return 5;
		else return 6;
	}
	
	public boolean AP_QulifyLocationChanged(Location loc) {
		if( previousLocation == null 
		    || (previousLocation != null && loc.distanceTo(previousLocation) >= MinDistance)
		) {
			if(previousLocation != null)Log.i("AP","dist is "+loc.distanceTo(previousLocation));
			previousLocation = loc;
			setLocationChangedFlag(true);
			return true;
		} else {
			return false;
		}
	}
	
	public synchronized void setLocationChangedFlag(boolean flag) {
		Location_Changed_flag = flag;
	}
	
	public final GpsStatus.Listener gpsListener = new GpsStatus.Listener() {
		public void onGpsStatusChanged(int event) {
			//GpsStatus gpsStatus = BigPlanet.locationManager.getGpsStatus(null);
			switch(event) {
			case GpsStatus.GPS_EVENT_STARTED:
				Log.i("GPS", "GPS_EVENT_STARTED");
				mGPSStartTimeMillis = SystemClock.elapsedRealtime();
				GPSISWORKING = true;
				BigPlanet.showRefreshGPS(false);
				break;
			case GpsStatus.GPS_EVENT_FIRST_FIX:
				Log.i("GPS", "GPS_EVENT_FIRST_FIX");
				//isGPSFix = true;
				break;
			case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
				break;
			case GpsStatus.GPS_EVENT_STOPPED:
				Log.i("GPS", "GPS_EVENT_STOPPED");
				GPSISWORKING = false;
				if(PauseGear>=3) BigPlanet.showRefreshGPS(true);
				break;
			}

		}
	};
	
}


